package com.wenqian.server.core;

import com.wenqian.server.http.HttpRequest;
import com.wenqian.server.http.HttpResponse;

import java.io.*;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

// Handle : 处理
public class RequestHandle implements Runnable {
    private final Socket socket;
    private final String webRoot;

    public RequestHandle(Socket socket, String webRoot){
        this.socket = socket;
        this.webRoot = webRoot;
    }


    @Override
    public void run() {
        try (
                InputStream in = socket.getInputStream();
                OutputStream out = socket.getOutputStream()
        ) {
            // 1. 解析HTTP请求
            HttpRequest request = HttpRequest.parse(in);
            System.out.println("处理请求: " + request.getMethod() + " " + request.getPath());

            // 2. 创建HTTP响应
            HttpResponse response = new HttpResponse();

            // 3. 根据请求方法进行处理
            if ("GET".equalsIgnoreCase(request.getMethod())){
                handleGet(request, response);
            } else if ("POST".equalsIgnoreCase(request.getMethod())) {
                handlePost(request, response);
            }

            // 4. 发送响应
            response.writeTo(out);

        } catch (Exception e) {
            System.err.println("处理请求时发生错误: " + e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                // ignore
            }
        }
    }



    private void handleGet(HttpRequest request, HttpResponse response) throws IOException {
        // 将URL路径映射到本地文件路径
        String path = request.getPath().equals("/") ? "/index.html" : request.getPath();
        Path filePath = Paths.get(webRoot, path).toAbsolutePath().normalize();

        // 安全检查：确保文件路径在webRoot目录下
        if (!filePath.startsWith(Paths.get(webRoot).toAbsolutePath())){
            response.setStatusCode(403, "Forbidden");
            response.addHeader("Content-Type", "text/html; charset=utf-8");
            response.setBody("<h1>403 Forbidden</h1>".getBytes());
            return;
        }

        if (Files.exists(filePath) && !Files.isDirectory(filePath)){
            byte[] fileBytes = Files.readAllBytes(filePath);
            response.setStatusCode(200, "OK");
            response.addHeader("Content-Type", getMimeType(filePath.toString()));
            response.addHeader("Content-Length", String.valueOf(fileBytes.length));
            response.setBody(fileBytes);
        } else {
            // 文件未找到，尝试发送自定义的 404.html
            Path notFoundPage = Paths.get(webRoot, "404.html");
            response.setStatusCode(404, "Not Found");
            response.addHeader("Content-Type", "text/html; charset=utf-8");

            if (Files.exists(notFoundPage)) {
                byte[] notFoundBytes = Files.readAllBytes(notFoundPage);
                response.setBody(notFoundBytes);
            } else {
                // 如果连 404.html 都没有，就返回一个默认的简单消息
                response.setBody("<h1>404 Not Found</h1>".getBytes());
            }
        }

    }

    private void handlePost(HttpRequest request, HttpResponse response) {
        if ("/submit".equals(request.getPath())) {
            // 这是提交表单的路径
            response.setStatusCode(200, "OK");
            response.addHeader("Content-Type", "text/html; charset=utf-8");

            // 从请求体中解析表单数据 (这是一个简化的解析，实际情况可能更复杂)
            String body = request.getBody();
            StringBuilder htmlResponse = new StringBuilder();
            htmlResponse.append("<html><head><title>POST Response</title><link rel=\"stylesheet\" href=\"/style.css\"></head><body>");
            htmlResponse.append("<div class='container'>");
            htmlResponse.append("<h1>POST 请求已收到!</h1>");
            htmlResponse.append("<p>感谢您的提交。服务器收到的原始数据如下：</p>");
            htmlResponse.append("<pre><code>").append(escapeHtml(body)).append("</code></pre>");
            htmlResponse.append("<br><a href=\"/\">返回主页</a>");
            htmlResponse.append("</div></body></html>");
            System.out.println(request.getBody());
            response.setBody(htmlResponse.toString().getBytes());
        } else {
            // 其他POST请求路径，返回404
            response.setStatusCode(404, "Not Found");
            response.addHeader("Content-Type", "text/html; charset=utf-8");
            response.setBody("<h1>404 Not Found</h1><p>POST endpoint not found.</p>".getBytes());
        }
    }

    // 辅助方法，防止HTML注入
    private String escapeHtml(String text) {
        if (text == null) return "";
        return text.replace("&", "&amp;")
                .replace("<", "&lt;")
                .replace(">", "&gt;")
                .replace("\"", "&quot;")
                .replace("'", "&#039;");
    }

    private String getMimeType(String fileName) {
        if (fileName.endsWith(".html") || fileName.endsWith(".htm")) return "text/html";
        if (fileName.endsWith(".css")) return "text/css";
        if (fileName.endsWith(".js")) return "application/javascript";
        if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) return "image/jpeg";
        if (fileName.endsWith(".png")) return "image/png";
        return "application/octet-stream"; // 默认的二进制流类型
    }
}
